﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Xml;
using Newtonsoft.Json;
using WSPay.Alipay;
using WSPay.Application;
using WSPay.Common;
using WSPay.Common.Log;
using WSPay.Core.DTO;

namespace WSPay.Web.Controllers
{
    /// <summary>
    /// 支付宝退款
    /// </summary>
    public class RefoundController : Controller
    {
        public IRefoundService _refoundService { get; private set; }
       
        public HttpClient _httpClient;

        public RefoundController(IRefoundService refoundService)
        {
            _httpClient = new HttpClient();
            _refoundService = refoundService;
        }

        public ActionResult Test(RefundOrderDto dto)
        {
            return View(dto);
        }

        public ActionResult Index()
        {
            try
            {
                NLogLogger nlog = new NLogLogger();
                string GATEWAY_NEW = "https://mapi.alipay.com/gateway.do?";
                var noticeUrl = Url.AbsoluteAction("RefundNotice", "Refund");
                var refundUrl = "refund_fastpay_by_platform_nopwd";
                //把请求参数打包成数组
                SortedDictionary<string, string> sParaTemp = new SortedDictionary<string, string>();
                sParaTemp.Add("service", refundUrl);
                sParaTemp.Add("partner", Config.partner);
                sParaTemp.Add("_input_charset", Config.input_charset.ToLower());
                sParaTemp.Add("notify_url", noticeUrl);
                sParaTemp.Add("seller_user_id", Config.partner);
                sParaTemp.Add("refund_date", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                sParaTemp.Add("batch_no", "040219998065");
                sParaTemp.Add("batch_num", "1");
                // 退款详细数据，必填，格式（支付宝交易号 ^ 退款金额 ^ 备注），多笔请用#隔开
                sParaTemp.Add("detail_data", "2017061821001004300293954114^4^测试退款");
                //建立请求
                var dicPara = AlipaySubmit.BuildRequestParaToString(sParaTemp, Encoding.UTF8);
                var response = _httpClient.GetAsync(GATEWAY_NEW + "?" + dicPara);
                string responseString = response.Result.Content.ReadAsStringAsync().Result;
                nlog.Info("支付宝返回数据：" + responseString);
                var xd = new XmlDocument();
                xd.LoadXml(responseString);
                XmlNode xmlRoot = xd.SelectSingleNode("alipay");
                if (xmlRoot != null)
                {
                    XmlNode result = xmlRoot.SelectSingleNode("is_success");
                    if (result.ChildNodes[0].InnerText == "T")
                        return Json("success", JsonRequestBehavior.AllowGet);
                }
                return Json("error", JsonRequestBehavior.AllowGet);
            }
            catch (Exception e)
            {
                return Json(e.Message);
            }
        }

        /// <summary>
        /// 退款
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public ActionResult Refund(RefundOrderDto dto)
        {
            try
            {
                NLogLogger nlog = new NLogLogger();
                string GATEWAY_NEW = "https://mapi.alipay.com/gateway.do?";
                var noticeUrl = Url.AbsoluteAction("RefundNotice", "Refund");
                var refundUrl = "refund_fastpay_by_platform_nopwd";
                nlog.Info("请求数据："+JsonConvert.SerializeObject(dto));
                var order = _refoundService.CreateRefundOrder(dto);
                //把请求参数打包成数组
                SortedDictionary<string, string> sParaTemp = new SortedDictionary<string, string>();
                sParaTemp.Add("service", refundUrl);
                sParaTemp.Add("partner", Config.partner);
                sParaTemp.Add("_input_charset", Config.input_charset.ToLower());
                sParaTemp.Add("notify_url", noticeUrl);
                sParaTemp.Add("seller_user_id",Config.partner);
                sParaTemp.Add("refund_date", order.CreateTime.ToString("yyyy-MM-dd HH:mm:ss"));
                sParaTemp.Add("batch_no",order.BatchNo);
                sParaTemp.Add("batch_num", "1");
                // 退款详细数据，必填，格式（支付宝交易号 ^ 退款金额 ^ 备注），多笔请用#隔开
                sParaTemp.Add("detail_data", order.NoticeSn+"^4^"+order.Remark);
                //建立请求
                var dicPara = AlipaySubmit.BuildRequestParaToString(sParaTemp,Encoding.UTF8);
                var response = _httpClient.GetAsync(GATEWAY_NEW+"?"+dicPara);
                string responseString = response.Result.Content.ReadAsStringAsync().Result;
                nlog.Info("支付宝返回数据：" + responseString);
                var xd = new XmlDocument();
                xd.LoadXml(responseString);
                XmlNode xmlRoot = xd.SelectSingleNode("alipay");
                if (xmlRoot != null)
                {
                    XmlNode result = xmlRoot.SelectSingleNode("is_success");
                    if(result.ChildNodes[0].InnerText=="T")
                    return Json("success",JsonRequestBehavior.AllowGet);
                }
                return Json("error", JsonRequestBehavior.AllowGet);
            }
            catch (Exception e)
            {
                return Json(e.Message);
            }
        }

       /// <summary>
       /// 支付宝通知
       /// </summary>
       /// <returns></returns>
        public ActionResult RefundNotice()
        {
            SortedDictionary<string, string> sPara = GetRequestPost();
            if (sPara.Count > 0)//判断是否有带返回参数
            {
                NLogLogger nlog = new NLogLogger();
                nlog.Info("支付宝通知数据："+JsonConvert.SerializeObject(sPara));
                AlipayNotify aliNotify = new AlipayNotify();
                bool verifyResult = aliNotify.Verify(sPara, Request.Form["notify_id"], Request.Form["sign"]);
                if (verifyResult)//验证成功
                {
                    string batch_no = Request.Form["batch_no"];
                    //批量退款数据中转账成功的笔数
                    string success_num = Request.Form["success_num"];
                    //批量退款数据中的详细信息
                    string result_details = Request.Form["result_details"];
                    //获取SUCCESS数据
                    string[] result = result_details.Split('^');
                    if (result.Contains("SUCCESS"))//退款成功
                    {
                        var refund = _refoundService.GetRefundOrderByBath(batch_no);
                        _refoundService.SuccessRefound(refund.ID, result_details);
                    }
                    else
                    {
                        var refund = _refoundService.GetRefundOrderByBath(batch_no);
                        _refoundService.FailureRefound(refund.ID, result_details);
                    }
                    return Json("success");  //请不要修改或删除              
                }
                else//验证失败
                {
                    return Json("fail");
                }
            }
            else
            {
                return Json("无通知参数");
            }
        }
        /// <summary>
        /// 获取支付宝POST过来通知消息，并以“参数名=参数值”的形式组成数组
        /// </summary>
        /// <returns>request回来的信息组成的数组</returns>
        public SortedDictionary<string, string> GetRequestPost()
        {
            int i = 0;
            SortedDictionary<string, string> sArray = new SortedDictionary<string, string>();
            NameValueCollection coll;
            coll = Request.Form;

            // Get names of all forms into a string array.
            String[] requestItem = coll.AllKeys;

            for (i = 0; i < requestItem.Length; i++)
            {
                sArray.Add(requestItem[i], Request.Form[requestItem[i]]);
            }

            return sArray;
        }
    }
}